package com.xz.member.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.annotation.DataScope;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.core.domain.entity.SysDept;
import com.xz.common.core.domain.entity.SysUser;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.diagnosisOrder.utils.DiagnosisOrderUtils;
import com.xz.enums.WalletRecordStatusEnum;
import com.xz.member.domain.*;
import com.xz.member.mapper.*;
import com.xz.member.service.IWalletRecordService;
import com.xz.member.vo.WalletRecordListVo;
import com.xz.member.vo.WalletRecordVo;
import com.xz.message.service.ISysTenantNotifyItemService;
import com.xz.message.vo.MemberMsgInfo;
import com.xz.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 钱包记录Service业务层处理
 *
 * @author xz
 * @date 2024-1-24 17:01:20
 */
@Service
public class WalletRecordServiceImpl extends ServiceImpl<WalletRecordMapper, WalletRecord> implements IWalletRecordService {

    @Resource
    private MemberInfoMapper memberInfoMapper;
    @Resource
    private RechargeActivityMapper rechargeActivityMapper;
    @Resource
    private RechargeActivityGiftMapper activityGiftMapper;
    @Resource
    private GiftReceiveMapper giftReceiveMapper;
    @Resource
    private MemberLevelMapper memberLevelMapper;
    @Autowired
    private ISysTenantNotifyItemService sysTenantNotifyItemService;
    @Resource
    private ISysDeptService sysDeptService;

    @Override
    public List<WalletRecord> listByMemberId(WalletRecord walletRecord) {
        List<WalletRecord> walletRecords = baseMapper.queryList(walletRecord);
        walletRecords.stream().forEach(o->{
            if(Objects.nonNull(walletRecord.getActivityId())){
                RechargeActivity activity = rechargeActivityMapper.selectById(walletRecord.getActivityId());
                o.setActivityName(activity.getActivityName());
            }
        });
        return walletRecords;
    }

    @Override
    @DataScope(deptAlias = "d")
    public List<WalletRecordListVo> queryVoList(WalletRecord walletRecord) {

        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<WalletRecordListVo> walletRecords = baseMapper.queryVoList(walletRecord);
        if (!CollectionUtils.isEmpty(walletRecords)) {
            walletRecords.forEach(vo->{
                // 设置会员信息
                String memberInfo = DiagnosisOrderUtils.getPatientInfo(vo.getMemberName(),vo.getSex(),vo.getBirthday());
                vo.setMemberInfo(memberInfo);
                //如果是消费退款，则为钱包负数
                Integer changeType = vo.getChangeType();
                final boolean isConsumption = null != changeType && (changeType.equals(3) || changeType.equals(5)
                        || changeType.equals(7) || changeType.equals(12));
                if(isConsumption){
                    vo.setPaymentAmount(vo.getChangeValue().multiply(new BigDecimal(-1)));
                }else{
                    // 设置充值金额，钱包支付
                    Integer changeValueType = vo.getChangeValueType();
                    if(null != changeValueType){
                        if(1 == changeValueType.intValue()){
                            vo.setRechargeAmount(vo.getChangeValue());
                        }else if(2 == changeValueType.intValue()){
                            vo.setPaymentAmount(vo.getChangeValue());
                        }
                    }
                }
            });
        }
        return walletRecords;
    }

    @Override
    public AjaxResult memberWallet(WalletRecord walletRecord) {
        WalletRecordVo vo = new WalletRecordVo();
        MemberInfo memberInfo = memberInfoMapper.selectById(walletRecord.getMemberId());
        vo.setWalletBalance(memberInfo.getWalletBalance());
        BigDecimal bigDecimal = baseMapper.sumMemberWallet(memberInfo.getMemberCardNo());
        vo.setAccumulatedRecharge(bigDecimal);
        return AjaxResult.success(vo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult addRecord(WalletRecord walletRecord){
        Integer changeValueType = walletRecord.getChangeValueType();
        BigDecimal changeValue = walletRecord.getChangeValue();
        Integer changeType = walletRecord.getChangeType();
        Integer nameStatus = WalletRecordStatusEnum.typeOf(changeValueType).getName();
        walletRecord.setStatus(nameStatus);
        MemberInfo memberInfo = memberInfoMapper.selectById(walletRecord.getMemberId());
        walletRecord.setMemberCardNo(memberInfo.getMemberCardNo());
        BigDecimal walletBalance = memberInfo.getWalletBalance();
        String no = "";
        if(changeType.equals(1)){
            // 构建单号
            no = RedisCode.getCode("CZ");
            walletRecord.setRelatedNo(no);
            // 累计充值金额
            BigDecimal accumulatedRecharge = memberInfo.getAccumulatedRecharge();
            accumulatedRecharge = accumulatedRecharge.add(changeValue);
            memberInfo.setAccumulatedRecharge(accumulatedRecharge);
        }else if(changeType.equals(2)){
            no = RedisCode.getCode("QBTK");
            walletRecord.setRelatedNo(no);
        }
        if(changeType % 2 == 0){
            BigDecimal subtract = walletBalance.subtract(changeValue);
            if(!changeType.equals(2)){
                memberInfo.setWalletBalance(subtract);
            }else {
                if(subtract.doubleValue()<0){
                    return AjaxResult.error("钱包余额不足！");
                }
            }
            if(changeType.equals(2)){// 退款就是退款成功
                walletRecord.setStatus(4);
            }
            memberInfo.setWalletBalance(subtract);
            walletRecord.setChangeValueType(2);
        }else {
            BigDecimal add = walletBalance.add(changeValue);
            memberInfo.setWalletBalance(add);
            walletRecord.setChangeValueType(1);
        }
        // 更新用户信息
        memberInfoMapper.updateById(memberInfo);

        // rechargeMethod: 充值方式（充值用） 1-活动充值. 2.自由充值
        // 如果不是活动充值，把活动id去掉，避免前端在自由充值的情况下，还传活动id
        if(null != walletRecord.getRechargeMethod() && 2 == walletRecord.getRechargeMethod().intValue()){
            walletRecord.setActivityId(null);
        }

        // 创建人，创建租户，创建时间，创建部门
        LoginUser loginUser = SecurityUtils.getLoginUser();
        walletRecord.setCreateBy(loginUser.getUserId());
        walletRecord.setTenantId(loginUser.getTenantId());
        if(null == walletRecord.getDeptId()){
            walletRecord.setDeptId(loginUser.getDeptId());
            walletRecord.setDeptName(loginUser.getUser().getDeptName());
        }
        walletRecord.setCreateTime(new Date());
        // 新增充值记录
        baseMapper.insert(walletRecord);

        if(Objects.nonNull(walletRecord.getActivityId())){
            // 说明参加充值活动
            RechargeActivity rechargeActivity = rechargeActivityMapper.selectById(walletRecord.getActivityId());
            Integer ifGift = rechargeActivity.getIfGift();
            if(ifGift.equals(1)){
                List<RechargeActivityGift> listByActivityId = activityGiftMapper.findListByActivityId(walletRecord.getActivityId());
                for (RechargeActivityGift gift:listByActivityId) {
                    GiftReceive giftReceive = new GiftReceive();
                    giftReceive.setMemberCardNo(walletRecord.getMemberCardNo());
                    String giftCategory = gift.getGiftCategory();
                    BigDecimal giftValue = gift.getGiftValue();
                    String giftName = "价值"+giftValue+"的"+giftCategory;
                    giftReceive.setGiftName(giftName);
                    giftReceive.setGiftValue(giftValue);
                    giftReceive.setReceiveReason(rechargeActivity.getActivityName());
                    giftReceive.setRelatedRechargeNo(no);
                    giftReceiveMapper.insert(giftReceive);
                }
            }
            if(Objects.nonNull(rechargeActivity.getMemberLevelId())){
                MemberLevel memberLevel = memberLevelMapper.selectById(rechargeActivity.getMemberLevelId());
                if(Objects.nonNull(memberInfo.getMemberLevelId())){
                    if(memberInfo.getMemberLevelId() < rechargeActivity.getMemberLevelId() ){
                        memberInfo.setMemberLevelId(rechargeActivity.getMemberLevelId());
                        memberInfo.setMemberLevel(memberLevel.getLevelNo());
                        memberInfoMapper.updateById(memberInfo);
                    }
                }else {
                    memberInfo.setMemberLevelId(memberLevel.getId());
                    memberInfo.setMemberLevel(memberLevel.getLevelNo());
                    memberInfoMapper.updateById(memberInfo);
                }
            }
        }
        // 判断会员注销
        if(Objects.nonNull(walletRecord.getWhetherCancel()) && walletRecord.getWhetherCancel().equals(1) ){
            memberInfoMapper.cancelMember(memberInfo.getId());
        }
        // 发送短信
        if(changeType.equals(1)){
            sendSms(walletRecord, memberInfo, 0);// 短信的类型：0.会员钱包充值
        }else if(changeType.equals(2)){
            sendSms(walletRecord, memberInfo, 3);// 短信的类型：3.会员钱包退款
        }
        return AjaxResult.success("操作成功！");
    }

    /**
     * 充值记录·短信发送
     * @param walletRecord
     * @param memberInfo
     * @param msgTypes
     */
    private void sendSms(WalletRecord walletRecord, MemberInfo memberInfo, int msgTypes) {

        // 提取短信关键字，从“此次变动记录”中：
        MemberMsgInfo msgInfo = new MemberMsgInfo();
        msgInfo.setMemberCardNo(walletRecord.getMemberCardNo());
        msgInfo.setPhoneNumber(memberInfo.getPhoneNumber());
        msgInfo.setVariableAmount(walletRecord.getChangeValue());
        msgInfo.setDeptId(walletRecord.getDeptId());
        msgInfo.setOperateStores(walletRecord.getDeptName());
        SysDept dept = sysDeptService.selectDeptById(msgInfo.getDeptId());
        if(null != dept){
            msgInfo.setStorePhone(dept.getPhone());
        }
        msgInfo.setTenantId(walletRecord.getTenantId());
        // 提取短信关键字，从“钱包信息(变动后的)”中：
        msgInfo.setWalletBalance(memberInfo.getWalletBalance());
        msgInfo.setIntegralBalance(memberInfo.getIntegralBalance());
        // 这个User没有特殊意义，只是通用方法中，用于构建短信日志的创建人信息
        SysUser user = SecurityUtils.getLoginUser().getUser();
        sysTenantNotifyItemService.sendMemberInfoMsg(msgInfo, msgTypes, user);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult cancelWalletRecord(WalletRecord walletRecord){

        // 检索充值记录
        WalletRecord record = baseMapper.selectById(walletRecord.getId());
        // 检索会员信息
        MemberInfo memberInfo = memberInfoMapper.memberInfoByCardNo(record.getMemberCardNo());
        if(record.getChangeType().equals(2)){
            // 钱包退款 - 退款作废
            if(record.getStatus().equals(4)){
                // 需要把退款的钱 返回给钱包
                BigDecimal changeValue = record.getChangeValue();
                BigDecimal walletBalance = memberInfo.getWalletBalance();
                memberInfo.setWalletBalance(walletBalance.add(changeValue));
                memberInfoMapper.updateById(memberInfo);
            }
            record.setStatus(6);
            record.setUpdateBy(SecurityUtils.getLoginUser().getUserId());
            record.setUpdateTime(new Date());
            baseMapper.updateById(record);

        }else if(record.getChangeType().equals(1)){
            // 充值作废
            // 作废后的会员余额 = 当前会员余额 - 充值单余额
            BigDecimal walletBalance = memberInfo.getWalletBalance();
            BigDecimal changeValue = record.getChangeValue();
            BigDecimal subtract = walletBalance.subtract(changeValue);
            memberInfo.setWalletBalance(subtract);
            //余额必须大于等0
            if(-1 == subtract.compareTo(BigDecimal.ZERO)){
                throw new ServiceException("余额不足，无法作废充值单");
            }

            // 变更会员等级
            if(Objects.nonNull(walletRecord.getAdjustLevelId())){
                memberInfo.setMemberLevelId(walletRecord.getAdjustLevelId());
                memberInfo.setMemberLevel(walletRecord.getAdjustLevel());
            }
            // 充值作废，要重新计算累计金额，这里先统计充值金额
            BigDecimal sumMemberWallet = baseMapper.sumMemberWallet(memberInfo.getMemberCardNo());
            // 统计充值金额减去此次作废金额
            // 这里避免拿会员原本的冗余的字段去减，因为会员冗余字段会因为历史等原因，不准。
            BigDecimal accumulatedRecharge = sumMemberWallet.subtract(record.getChangeValue());
            memberInfo.setAccumulatedRecharge(accumulatedRecharge);

            // 更新会员
            memberInfoMapper.updateById(memberInfo);
            // 判断是否需要注销会员
            if(Objects.nonNull(walletRecord.getWhetherCancel()) && walletRecord.getWhetherCancel().equals(1)){
                // 注销会员
                memberInfoMapper.cancelMember(record.getMemberId());
            }

            // 标记记录状态为充值作废
            record.setStatus(5);
            record.setUpdateBy(SecurityUtils.getLoginUser().getUserId());
            record.setUpdateTime(new Date());
            baseMapper.updateById(record);
        }
        return AjaxResult.success("操作成功！");
    }

    @Override
    public int addBizRecord(String memberCardNo, Integer changeType, Integer changeValueType, String relatedNo, BigDecimal changeValue,Long deptId){
        WalletRecord walletRecord =new WalletRecord();
        walletRecord.setMemberCardNo(memberCardNo);
        walletRecord.setChangeType(changeType);
        walletRecord.setChangeValue(changeValue);
        walletRecord.setChangeValueType(changeValueType);
        walletRecord.setRelatedNo(relatedNo);
        if(changeType.equals(3) || changeType.equals(5) || changeType.equals(7)){
            // 销售单，诊疗单，挂号单“退费”均需要把状态设置为4（退款成功）
            walletRecord.setStatus(4);
        }else if(changeType.equals(4) || changeType.equals(6) || changeType.equals(8)){
            // 销售单，诊疗单，挂号单“消费”均需要把状态设置为2（扣费成功）
            walletRecord.setStatus(2);
        }
        walletRecord.setDeptId(deptId);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        walletRecord.setCreateBy(null == loginUser ? null : loginUser.getUserId());
        walletRecord.setCreateTime(new Date());
        int insert = baseMapper.insert(walletRecord);
        return insert;
    }
}
